package com.hckjsec.common.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hckjsec.common.utils.AESUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @ Author     ：hanxi
 * @ Date       ：Created in 1:51 2025/3/6
 * @ Description：
 */
public class DecodeFilter implements Filter {


    private static String aesKey = "9c7s8gr2bg3ry02i";


    private static Logger logger = LoggerFactory.getLogger(DecodeFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.info("DecodeFilter initialized");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String uri = request.getRequestURI();
        logger.info("请求接口路径：{}",uri);
        response.setCharacterEncoding("UTF-8");
        //对非验签接口路径放行
        if (!StringUtils.contains(uri, "/wechat/api")) {
            filterChain.doFilter(request, response);
            return;
        }

        // 1. 读取加密的请求体
        boolean flag = true;
        String encryptedBody = readRequestBody(request);
        logger.info("读取加密的请求体:{}",encryptedBody);

        if(StringUtils.isEmpty(encryptedBody)){
            flag = false;
            String data = request.getParameter("data");
            logger.info("读取params加密参数data:{}",data);
            Map<String,Object> map = new HashMap<>();
            map.put("data",data);
            encryptedBody = JSON.toJSONString(map);
        }

        if(flag){
            try {
                // 2. AES解密
                String decryptedBody = decodeParams(encryptedBody);

                // 3. 创建新的Request对象（携带解密后的数据）
                DecryptRequestWrapper requestWrapper = new DecryptRequestWrapper(request, decryptedBody);

                // 4. 继续处理请求
                filterChain.doFilter(requestWrapper, response);
            } catch (Exception e) {
                // 解密失败处理
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                response.getWriter().write("{\"code\":400,\"message\":\"解密失败\"}");
            }
        }else {
            try {
                String decryptedBody = decodeParams(encryptedBody);
                DecryptRequestWrapper requestWrapper = new DecryptRequestWrapper(request, decryptedBody);
                filterChain.doFilter(requestWrapper, response);
            } catch (Exception e) {
                e.printStackTrace();
            }


        }

    }

    private String readRequestBody(HttpServletRequest request) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
        }
        return stringBuilder.toString();
    }


    /**
     * 解密参数
     *
     * @return
     * @throws Exception
     */
    private String decodeParams(String streamContent) throws Exception {
        //判断签名
        //logger.info("解密前:"+streamContent);
        if (StringUtils.isBlank(streamContent)) {
            logger.warn("streamContent is empty！");
        }
        JSONObject jsonObject = JSON.parseObject(streamContent);
        String params = jsonObject.getString("data");
        //rsa解密数据
//        params = URLDecoder.decode(params, "UTF-8");
        params = AESUtil.Decrypt(params, aesKey);
        logger.info("解密后:" + params);
        return params;
    }

    /**
     * 解密参数
     *
     * @return
     * @throws Exception
     */
    private String decodeParams2(String data) throws Exception {
        data = AESUtil.Decrypt(data, aesKey);
        logger.info("解密后:" + data);
        return data;
    }


    @Override
    public void destroy() {
        logger.info("DecodeFilter destroy");
    }
}
